//
//  LocalCache.m
//  lumihui
//
//  Created by oceans on 2018/10/27.
//  Copyright © 2018 ios. All rights reserved.
//

#import "LocalCache.h"
#import <CommonCrypto/CommonDigest.h>

static LocalCache *shared;

static NSString *userDefaultsKeys = @"cache_nsuserdefaults_keys";

@interface LocalCache()
@property (copy, nonatomic) NSString *cachePath;
@end

@implementation LocalCache

+ (instancetype)shared {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[self alloc] init];
    });
    return shared;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [super allocWithZone:zone];
    });
    return shared;
}

- (id)copyWithZone:(NSZone *)zone {
    return shared;
}

- (instancetype)init {
    self = [super init];
    if (self) {
    }
    return self;
}

#pragma mark - nsuserdefautls
/**用nsuserdefaults 缓存object*/
- (void)setPlistValue:(id)value forKey:(NSString *)key {
    
    [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
    [self addPlistValueKey:key];
}

/**用nsuserdefaults 缓存bool*/
- (void)setPlistBool:(BOOL)value forKey:(NSString *)key {
    
    [[NSUserDefaults standardUserDefaults] setBool:value forKey:key];
    [self addPlistValueKey:key];
}

- (id)getPlistValueForKey:(NSString *)key {
    return [[NSUserDefaults standardUserDefaults] objectForKey:key];
}

- (BOOL)getPlistBoolForKey:(NSString *)key {
    return [[NSUserDefaults standardUserDefaults] boolForKey:key];
}

/**用nsuserdefaults 缓存完 object或bool 把key存起来，退出登录时统一清理*/
- (void)addPlistValueKey:(NSString *)key {
    NSString *keys = [[NSUserDefaults standardUserDefaults] objectForKey:userDefaultsKeys];
    NSMutableString *userkeys = nil;
    if (keys) {
        userkeys = [NSMutableString stringWithString:keys];
    }else {
        userkeys = [NSMutableString string];
    }
    [userkeys appendString:key];
    [userkeys appendString:@","];
    [[NSUserDefaults standardUserDefaults] setObject:userkeys forKey:userDefaultsKeys];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

/**退出登录时，清理nsuserdefaults 缓存*/
- (void)clearNSUserDefaultsValues {
    
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSString *keys = [userDefaults objectForKey:userDefaultsKeys];
    if (keys && keys.length > 0) {
        NSArray *keyArr = [keys componentsSeparatedByString:@","];
        for (NSString *key in keyArr) {
            [userDefaults removeObjectForKey:key];
        }
    }
    
    [userDefaults removeObjectForKey:userDefaultsKeys];
    [userDefaults synchronize];
}

#pragma mark - nsuserdefaluts

- (void)clearAllCacheAndPlist {
    [self removeCache];
    [self clearNSUserDefaultsValues];
}

#pragma mark - file cache

- (void)removeCache {
    NSError *error;
    [[NSFileManager defaultManager] removeItemAtPath:self.cachePath error:&error];
    self.cachePath = nil;
    if (error) {
        NSLog(@"\n 清除 Cache 失败: %@\n", [error description]);
    }
}

- (void)removeCacheForKey:(NSString *)key {
    if ([[NSFileManager defaultManager] fileExistsAtPath:[self filePath:key]]) {
        NSError *error;
        [[NSFileManager defaultManager] removeItemAtPath:[self filePath:key] error:&error];
        if (error) {
            NSLog(@"\n清除cache for key 失败: %@\n", [error description]);
        }
    }
}

- (void)CacheData:(NSData *)data forKey:(NSString *)key {
    NSString *filePath = [self filePath:key];
    BOOL result = [data writeToFile:filePath atomically:YES];
    if (!result) {
        NSLog(@"cache 缓存 data 失败 key: %@", filePath);
    }
}

- (nullable NSData *)GetCache:(NSString *)key {
    if (![[NSFileManager defaultManager] fileExistsAtPath:[self filePath:key]]) {
        return nil;
    }
    return [[NSFileManager defaultManager] contentsAtPath:[self filePath:key]];
}

- (BOOL)ExistsFile:(NSString *)key {
    return [[NSFileManager defaultManager] fileExistsAtPath:[self filePath:key]];
}

- (NSString *)filePath:(NSString *)key {
    
    NSLog(@"------------------------- %@", [self.cachePath stringByAppendingString:[NSString stringWithFormat:@"/%@", [self md5:key]]]);
    return [self.cachePath stringByAppendingString:[NSString stringWithFormat:@"/%@", [self md5:key]]];
}

- (NSString *)cachePath {
    if (!_cachePath) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *baseDocPath = paths.firstObject;
        NSString *cachePath = [baseDocPath stringByAppendingString:@"/Cache"];
        NSFileManager *manager = [NSFileManager defaultManager];
        if (![manager fileExistsAtPath:cachePath]) {
            if ([self createCachePath:cachePath]) {
                _cachePath = cachePath;
            }
        }else {
            _cachePath = cachePath;
        }
    }
    return _cachePath;
}

- (BOOL)createCachePath:(NSString *)filePath {
    
    NSFileManager *manager = [NSFileManager defaultManager];
    NSError *error;
    BOOL result = [manager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error];
    if (error) {
        NSLog(@"创建Cache路径失败%@", [error description]);
    }
    return result;
}

- (NSString *)md5:(NSString *)string{
    
    const char *cStr = [string UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5(cStr, (CC_LONG)strlen(cStr), digest);
    
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%02X", digest[i]];
    }
    
    return result;
}

@end
